#ifndef PGRCAM_HPP
#define PGRCAM_HPP


//#ifdef WIN32
//#include "C:/Users/sandy/Desktop/PGR/FlyCapture2/include/C/FlyCapture2_C.h"
//#include "d:/Program Files/Point Grey Research/FlyCapture2/include/C/FlyCapture2_C.h"
#include "FlyCapture2_C.h"
#include <opencv2/opencv.hpp>


//! C:\\Program Files\\Point Grey Research\\PGR FlyCapture\\lib
//#pragma comment(lib, "flycapture2_C.lib")
//#pragma comment(lib, "flycapture2GUI_C.lib")

//#endif

//! cam for pgr
class PGRCam
{
public:
	PGRCam():m_img(NULL), m_numimg(0), m_valid(false) { m_bgrimage.pData = NULL; Open(); }
	~PGRCam(){ if(m_valid) Close(); }

public:
	void Get(IplImage* dst);
	IplImage* Get();

	bool Valid() const { return m_valid; }
	int GetNumImg() const { return m_numimg; }
	int GetW() const { return m_img->width; }
	int GetH() const { return m_img->height; }
	int GetDepth() const { return m_img->depth; }
	int GetChannel() const { return m_img->nChannels; }

private:
	void GetFly();
	void Open();
	void Close();

private:
	fc2Error m_error;
	fc2Context m_flycapture;
	fc2Image m_cameraimage;
    fc2Image m_bgrimage;

	IplImage* m_img;
	int m_numimg;
	bool m_valid;
};

///////////////////////////////////////////////////////////
//
//
//		public
//
//
///////////////////////////////////////////////////////////

void PGRCam::Get(IplImage* dst)
{
	GetFly();
	memcpy(dst->imageData, m_bgrimage.pData, m_bgrimage.dataSize);
}

//! get image (pointer should not be released in a function calling this function)
IplImage* PGRCam::Get()
{
	GetFly();	
	memcpy(m_img->imageData, m_bgrimage.pData, m_bgrimage.dataSize);
	return m_img;
}

///////////////////////////////////////////////////////////
//
//
//		private
//
//
///////////////////////////////////////////////////////////

void PGRCam::GetFly()
{
	m_error = fc2RetrieveBuffer(m_flycapture, &m_cameraimage);
    m_error = fc2ConvertImageTo(FC2_PIXEL_FORMAT_BGR, &m_cameraimage, &m_bgrimage);
	m_numimg++;
}


//! open camera
void PGRCam::Open()
{
    fc2PGRGuid guid;
    unsigned int numCameras = 0;    
    
    m_error = fc2CreateContext( &m_flycapture );
    if ( m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2CreateContext: %d\n", m_error );
        return;
    }        

    m_error = fc2GetNumOfCameras( m_flycapture, &numCameras );
    if (m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2GetNumOfCameras: %d\n", m_error );
        return;
    }

    if ( numCameras == 0 )
    {
        // No cameras detected
        printf( "No cameras detected.\n");
        return;
    }

    // Get the 0th camera
    m_error = fc2GetCameraFromIndex( m_flycapture, 0, &guid );
    if ( m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2GetCameraFromIndex: %d\n", m_error );
        return;
    }    

    m_error = fc2Connect( m_flycapture, &guid );
    if (m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2Connect: %d\n", m_error );
        return;
    }

	m_error = fc2SetVideoModeAndFrameRate(m_flycapture, FC2_VIDEOMODE_640x480RGB, FC2_FRAMERATE_60);
    if (m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2SetVideoMode: %d\n", m_error );
        return;
    }

    m_error = fc2StartCapture( m_flycapture );
    if ( m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2StartCapture: %d\n", m_error );
        return;
    }


    m_error = fc2CreateImage( &m_cameraimage );
    if ( m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2CreateImage: %d\n", m_error );
		return;
	}

	m_error = fc2CreateImage( &m_bgrimage );
    if ( m_error != FC2_ERROR_OK )
    {
        printf( "Error in fc2CreateImage: %d\n", m_error );
		return;
    }

	m_img = cvCreateImage(cvSize(640,480),8,3);

	m_valid = true;
}

//! close camera
void PGRCam::Close()
{
	//fc2StopCapture(m_flycapture);
	//flycaptureDestroyContext(m_flycapture);

	cvReleaseImage(&m_img);

	delete [] m_bgrimage.pData;
}

#endif